<template>
	<view class="music-vue">
		<view class="music">
			<view class="img-content">
				<view class="img-bg">
					<image src="@/static/pic/music.jpg" alt="music" />
				</view>
			</view>
			<view class="buttons">
				<text :class="['iconfont', `icon-${playType}`]" @click="changeType"></text>
				<u-icon name="rewind-left" color="#fff" size="10vw" @tap="lastMusic"></u-icon>
				<u-icon v-if="playing.filePath && innerAudioContext.id && !ifPause" name="pause-circle" color="#fff"
					size="20vw" @tap="pauseMusic"></u-icon>
				<u-icon v-else name="play-circle" color="#fff" size="20vw" @tap="playMusic('index')"></u-icon>
				<u-icon name="rewind-right" color="#fff" size="10vw" @tap="nextMusic"></u-icon>
				<text class="iconfont icon-gedan" @tap="openMusicList"></text>
			</view>
		</view>
		<u-overlay :show="show" @tap="show = false">
			<view class="scroll-content" :style="{transform: `translateX(${scrollLeft}px)`}" @touchstart="touchstart"
				@touchmove="touchmove" @touchend="touchend" @tap.stop>
				<view class="scroll-item" v-for="(item, ind) in musicList" :key="item.Id">
					<view class="musics">
						<view class="musics-top">
							<template v-if="ind === activeInd">
								<text :class="['iconfont', `icon-${playType}`]" @click="changeType"></text>
								<view class="buttons">
									<u-icon name="plus" color="#000" size="5vw" @tap="addMusicList(ind)"></u-icon>
									<u-icon v-if="musicList.length > 1" name="trash-fill" color="#000" size="6vw"
										@click="deleteList(ind)"></u-icon>
								</view>
							</template>
							<template v-else>
								<text></text>
								<u-icon name="play-circle-fill" color="#000" size="6vw"
									@tap="playMusic('overlay', ind)"></u-icon>
							</template>
						</view>
						<view class="musics-content">
							<view class="music-row" v-for="music in item.value" :key="music.filePath">
								<view
									:class="['music-name', ind === playing.index && music.filePath === playing.filePath ? 'playing' : '']"
									@tap="playMusic('item', {index: ind, filePath: music.filePath})">
									{{ music.displayName }}
								</view>
								<u-icon name="close" color="#000" size="4vw"
									@tap="deleteMusic(ind, music.filePath)"></u-icon>
							</view>
						</view>
					</view>
				</view>
			</view>
		</u-overlay>
		<view class="loading" v-if="showLoading">
			<u-loading-icon color="white" :show="showLoading"></u-loading-icon>
		</view>
	</view>
</template>

<script>
	export default {
		name: "music",
		data() {
			return {
				show: false,
				musicList: JSON.parse(uni.getStorageSync("musicList") || "[]"),
				localMusicList: [],
				showLoading: false,
				activeInd: JSON.parse(uni.getStorageSync("activeInd") || "0"),
				playType: "suijibofang",
				startPosition: 0,
				endPosition: 0,
				lastSroll: 0,
				scrollLeft: 0,
				tempInd: 0,
				playing: {},
				innerAudioContext: {},
				playStack: [],
				stackInd: 0,
				ifPause: false
			}
		},
		watch: {
			musicList: {
				handler(newVal) {
					uni.setStorageSync("musicList", JSON.stringify(newVal))
				},
				immediate: true,
				deep: true
			},
			activeInd: {
				handler(newVal) {
					uni.setStorageSync("activeInd", JSON.stringify(newVal))
				},
				immediate: true,
			}
		},
		methods: {
			openMusicList() {
				// 初始位置校准
				this.tempInd = this.activeInd
				let _this = this
				uni.getSystemInfo({
					success(systemInfo) {
						_this.lastSroll = -(systemInfo.windowWidth * 0.84) * _this.tempInd
						_this.scrollLeft = _this.lastSroll
					}
				})
				if (!this.musicList.length) {
					// #ifdef APP
					// 获取本地文件中的音频文件
					this.$nextTick(() => {
						this.addMusicList()
						this.activeInd = 0
						this.show = true
					})
					// #endif
					this.show = true
				} else {
					this.show = true
				}
			},
			getMusicList(file) {
				if (uni.getSystemInfoSync().platform === "android") {
					// native.js获取歌曲列表
					this.localMusicList = [];
					const MediaStore = plus.android.importClass('android.provider.MediaStore');
					const audioColumns = [
						MediaStore.Audio.Media.DISPLAY_NAME, // 歌曲名称
						MediaStore.Audio.Media.MIME_TYPE, // 歌曲的播放格式
						MediaStore.Audio.Media.DATA, // 歌曲文件的路径
					];
					const Main = plus.android.runtimeMainActivity();
					const Resolver = Main.getContentResolver();
					plus.android.importClass(Resolver);
					const cursor = Resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, audioColumns, null, null,
						null);
					plus.android.importClass(cursor);
					while (cursor != null && cursor.moveToNext()) {
						const displayName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media
							.DISPLAY_NAME));
						const mimtType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.MIME_TYPE));
						const filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
						if (mimtType === "audio/mpeg") {
							// mp3格式
							this.localMusicList.push({
								displayName,
								filePath,
							})
						}
					}
					cursor.close();
				}
			},
			changeType() {
				let playList = ['suijibofang', '16gl-repeat2', 'danquxunhuan']
				let currentInd = playList.findIndex((item) => item === this.playType)
				this.playType = playList[(currentInd + 1) % 3]
			},
			touchstart(e) {
				this.startPosition = e.changedTouches[0].clientX
			},
			touchmove(e) {
				this.scrollLeft = this.lastSroll + e.changedTouches[0].clientX - this.startPosition
			},
			touchend(e) {
				let _this = this
				uni.getSystemInfo({
					success(systemInfo) {
						let moveLength = e.changedTouches[0].clientX - _this.startPosition
						if (Math.abs(moveLength) > systemInfo.windowWidth / 3) {
							if (moveLength > 0 && _this.tempInd !== 0) {
								// 向左移动
								_this.scrollLeft = -(systemInfo.windowWidth * 0.84) * --_this.tempInd
							} else if (moveLength < 0 && _this.tempInd !== _this.musicList.length - 1) {
								// 向右移动
								_this.scrollLeft = -(systemInfo.windowWidth * 0.84) * ++_this.tempInd
							} else {
								_this.scrollLeft = -(systemInfo.windowWidth * 0.84) * _this.tempInd
							}
						} else {
							_this.scrollLeft = -(systemInfo.windowWidth * 0.84) * _this.tempInd
						}
						_this.lastSroll = _this.scrollLeft
					}
				})
			},
			async playMusic(type, info) {
				if (!this.innerAudioContext.id) {
					this.innerAudioContext = uni.createInnerAudioContext();
				}
				let ifPushStack = true
				if (type === "overlay") {
					// 列表播放按钮
					let filePath = this.musicList[info].value[0].filePath
					this.updatePlay(info, filePath, {
						index: info,
						filePath
					})
				} else if (type === "item") {
					// 点击歌单歌曲
					this.updatePlay(info.index, info.filePath, info)
				} else {
					// 首页播放按钮
					let filePath = ""
					if (this.innerAudioContext._options.src) {
						// 有暂停的音乐
						this.innerAudioContext.play()
						this.ifPause = false
						ifPushStack = false
					} else {
						if (this.musicList.length) {
							filePath = this.musicList[this.activeInd].value[0].filePath
							this.updatePlay(this.activeInd, filePath, {
								index: this.activeInd,
								filePath
							})
						} else {
							await this.addMusicList()
							this.$nextTick(() => {
								filePath = this.musicList[0].value[0].filePath
								this.updatePlay(0, filePath, {
									index: 0,
									filePath
								})
							})
						}
					}
				}
				if (ifPushStack) {
					this.playStack.splice(this.stackInd)
					this.playStack.push(this.playing)
					this.stackInd++
				}
				// 播放完毕
				this.innerAudioContext.onEnded(this.nextMusic)
			},
			pauseMusic() {
				this.innerAudioContext.pause()
				this.ifPause = true
			},
			lastMusic() {
				if (this.playStack.length > 1) {
					let lastPlaying = this.playStack[--this.stackInd - 1]
					this.updatePlay(this.activeInd, lastPlaying.filePath, lastPlaying)
				} else {
					this.playMusic("index")
				}
			},
			nextMusic() {
				let musicList = this.musicList[this.activeInd].value
				let filePath = ""
				let ifPushStack = true
				if (this.stackInd === this.playStack.length) {
					if (this.playType === "suijibofang") {
						// 随机播放
						let maxInd = this.musicList[this.activeInd].value.length - 1
						let randomInd = Math.floor(Math.random() * (maxInd + 1))
						filePath = musicList[randomInd].filePath
					} else if (this.playType === "16gl-repeat2") {
						// 循环播放
						let currentInd = -1
						musicList.forEach((item, ind) => {
							if (item.filePath === this.playing.filePath) {
								currentInd = ind
							}
						})
						filePath = musicList[(currentInd + 1) % musicList.length].filePath
					} else {
						// 单曲循环
						filePath = this.playing.filePath
						ifPushStack = false
					}
					this.updatePlay(this.activeInd, filePath, {
						index: this.activeInd,
						filePath
					})
					if (ifPushStack) {
						this.playStack.push(this.playing)
						this.stackInd++
					}
				} else {
					let nextPlaying = this.playStack[this.stackInd++]
					this.updatePlay(this.activeInd, nextPlaying.filePath, nextPlaying)
				}
			},
			deleteMusic(rowIndex, filePath) {
				this.musicList[rowIndex].value =
					this.musicList[rowIndex].value.filter(item => {
						return item.filePath !== filePath
					})
			},
			addMusicList() {
				this.showLoading = true
				this.localMusicList = []
				this.$nextTick(() => {
					this.getMusicList()
					this.$nextTick(() => {
						this.musicList.push({
							Id: +new Date(),
							value: this.localMusicList
						})
					})
					this.showLoading = false
				})
			},
			updatePlay(activeInd, filePath, playing) {
				this.ifPause = false
				this.activeInd = activeInd
				this.innerAudioContext.src = filePath
				this.innerAudioContext.play()
				this.playing = playing
			},
			deleteList(index) {
				this.musicList = this.musicList.filter((item, ind) => {
					return ind !== index
				})
				this.playing = {}
				if (this.musicList.length === 1) {
					this.activeInd = 0
					this.scrollLeft = 0
					this.tempInd = 0
					this.innerAudioContext = {}
				}
			}
		},
	}
</script>

<style lang="less">
	.music-vue {
		height: 100%;

		.music {
			height: 100%;
			display: flex;
			flex-direction: column;
			justify-content: space-between;
			align-items: center;

			&[hidden] {
				display: none;
			}

			.img-content {
				flex: 1;
				display: flex;
				align-items: center;

				.img-bg {
					width: 300px;
					height: 300px;
					border-radius: 50%;
					overflow: hidden;
					transform: scale(.8);

					image {
						width: 300px;
						height: 300px;
						transform: scale(1.2);
					}
				}
			}

			.buttons {
				display: flex;
				justify-content: center;
				align-items: center;
				margin-bottom: 10vh;

				.u-icon:nth-child(3) {
					margin: 0 4vw;
				}

				text.iconfont {
					color: #fff;
					font-size: 8vw;
					margin: 0 4vw;
				}
			}
		}

		.scroll-content {
			position: absolute;
			left: 8vw;
			bottom: 0;
			height: 70vh;
			display: flex;
			transition: all .2s;

			.scroll-item {
				width: 84vw;
				height: 100%;
				padding: 20px 3vw;
				box-sizing: border-box;
				background-color: transparent;

				.musics {
					width: 100%;
					height: 100%;
					background-color: #ccc;
					border-radius: 30px;
					padding: 20px;
					box-sizing: border-box;
					display: flex;
					flex-direction: column;

					.musics-top {
						display: flex;
						justify-content: space-between;

						.iconfont {
							font-size: 6vw;
							color: #000;
							margin-right: 10px;
						}

						.buttons {
							display: flex;
							justify-content: center;

							.u-icon {
								margin-right: 10px;

								&:last-child {
									margin-right: 0;
								}
							}
						}
					}

					.musics-content {
						display: flex;
						flex-direction: column;
						flex: 1;
						overflow-y: scroll;
						margin: 10px 0;

						.music-row {
							display: flex;
							justify-content: space-between;
							padding: 6px 0;

							.music-name {
								max-width: 80%;
								color: #000;
								white-space: nowrap;
								overflow: hidden;
								text-overflow: ellipsis;

								&.playing {
									color: red;
								}
							}
						}
					}
				}
			}
		}

		.loading {
			width: 100vw;
			height: 100vh;
			background-color: rgba(0, 0, 0, .5);
			display: flex;
			justify-content: center;
			align-items: center;
			z-index: 99999;
			position: absolute;
			top: 0;
			left: 0;
		}
	}
</style>